//
// Created by Crestimes on 24-6-2.
//

#ifndef PRODUCTION_H
#define PRODUCTION_H
#include <ostream>
#include <vector>

#include "Character.h"
using namespace std;


// 文法语句类
class Production {
public:
    Production() = default;

    Production(Character* left, const vector<Character*>& right, const int productionIndex,
               const vector<int>& buildTypes)
        : left(left), right(right), productionIndex(productionIndex), buildTypes(buildTypes) {
    }

    friend std::ostream& operator<<(std::ostream& os, const Production& obj) {
        os << "production[" << obj.productionIndex << "]\t" << obj.left->name << " ----> ";
        for (size_t i = 0; i < obj.right.size(); i++) {
            if (i == obj.pointIndex) {
                os << " . ";
            }
            os << " " << obj.right[i]->name << " ";
        }
        if (obj.pointIndex == obj.right.size()) {
            os << ".";
        }
        if (!obj.expectationSet.empty()) {
            os << "\t\t{ ";
            for (const auto& c : obj.expectationSet) {
                os << c->name << ", ";
            }
            os << " }";
        }
        return os;
    }

    [[nodiscard]] string toString(const bool& addExpectationSet) const; // 将文法句子的所有符号名称拼接成字符串返回

    Character* left{}; // 左侧非终结符
    vector<Character*> right; // 右侧符号序列
    set<Character*> expectationSet; // LR(1)中每个文法语句项右侧多了的期望集合，该集合由计算上一个产生式中本非终结符(left)后续的符号序列的First_S集合而来
    size_t pointIndex = 0; // LR(1)中节点中该文法语句的移进点所处的下标
    size_t productionIndex = 0; // 该文法语句在文法语句列表中的下标(用于分析表中判断按哪一条文法规约)
    vector<int> buildTypes; // 文法语句右侧元素在建立语法树时的操作（舍弃/作为子节点/作为根节点，标记值于global.h文件）
};


#endif //PRODUCTION_H
